
require(["util/domReady!", // Waits for page load
    "display",
    "util/gl-util",
    "util",
    //"programs",
   // "js/bolomap.js",
    "js/boloworld.js",
    "js/meshes/testmesh.js",
    //"js/textures.js",
    "js/util/gl-matrix.js",
	
    ], function(doc, display, glUtil,util,boloworld,meshes) { //bolomap,textures
    "use strict";
    // Create gl context and start the render loop 
    var canvas = document.getElementById("canvas");
    var frame = document.getElementById("display-frame");
    var fpsCounter = document.getElementById("fps");
    var gl = glUtil.getContext(canvas);


    var display = new display.display(gl, canvas);

    if(!gl) {
        // Replace the canvas with a message that instructs them on how to get a WebGL enabled browser
        glUtil.showGLFailed(frame); 
        return;
    }

    // If we don't set this here, the rendering will be skewed
    canvas.width = canvas.offsetWidth;
    canvas.height = canvas.offsetHeight;    
    display.resize(gl, canvas);

    boloworld.initWorld();
    
    boloworld.makeScene(gl,display);
    
    function alphaKeyPressed(k){
        if(display.cameraModule.KeyboardState._pressedKeys[k.charCodeAt(0)])
            return true;
        return false;
    }
    
    function keyCodePressed(kc){
        if(display.cameraModule.KeyboardState._pressedKeys[kc])
            return true;
        return false;
    }
    
    function moveObject(obj,dx,dy,dz,rad){
        var pmat=obj.matrix;
        var newX=pmat[12]+dx;
        var newY=pmat[13]+dy;

        if(rad){
            if(boloworld.radiusPassable(newX,newY,rad)==false){
                if(boloworld.radiusPassable(newX,pmat[13],rad)){//Can move x
                    newY=pmat[13];
                }else if(boloworld.radiusPassable(pmat[12],newY,rad)){//Can move y
                    newX=pmat[12];
                }else{              //Can't move
                    newX=pmat[12];
                    newY=pmat[13];
                }
            }
        }else{
            if(boloworld.cellPassable(boloworld.getCellAtWorld(newX,newY))==false){
                if(boloworld.cellPassable(boloworld.getCellAtWorld(newX,pmat[13]))){//Can move x
                    newY=pmat[13];
                }else if(boloworld.cellPassable(boloworld.getCellAtWorld(pmat[12],newY))){//Can move y
                    newX=pmat[12];
                }else{              //Can't move
                    newX=pmat[12];
                    newY=pmat[13];
                }
            }
        }
        pmat[12]=newX;
        pmat[13]=newY;
    }
    
    var v3t0=[0,0,0];
    var explosionMesh=display.mesh(gl,meshes.explosion)
    var explosionRenderer = boloworld.createSingleMeshRenderer("explosion");
    
    function projectileUpdate(){
        
        moveObject(this,this.velocity[0],this.velocity[1],this.velocity[2]);
        //this.matrix[12]+=this.velocity[0];
        //this.matrix[13]+=this.velocity[1];
        this.life--;
        if(this.life<50){
            if(this.life<=0){
                this.active=false; //Die.
            }else{
                if(this.life==45){
                    this.removeComponent(this.meshRenderer);
                    this.addComponent('meshRenderer',explosionRenderer);
                }
            }
        }
    }
    
    function fireProjectile(owner){
        var bullet=boloworld.addObject("bullet",[owner.matrix[12],owner.matrix[13],0.0]);
        
        bullet.update=projectileUpdate;
        bullet.life=100;
        mat4.getRowV3(owner.matrix, 1, v3t0);
        
        bullet.velocity=vec3.scale(v3t0, 6.0, [0,0,0]);
        mat4.set(owner.matrix,bullet.matrix);
        
        vec3.scale(v3t0,boloworld.worldMeter*3.0,v3t0);
        bullet.matrix[12]+=v3t0[0];
        bullet.matrix[13]+=v3t0[1];
        
    }

    
    var lastTile=null;
    
    var p=boloworld.players[0];
    
    p.avatar.camTarget=[0,0,0];
    p.avatar.angle=0;
    p.avatar.speed=0;
    display.camera.setCenter(p.avatar.camTarget);
    p.avatar.update=function    playerUpdate(){
        
        var accel=0.1;
        var rspeed=0.03;
        
        var impulseVel=0.0;
        var tankRad=40.0;
        
        //AWSD movement
        //Arrow key movement
        if(alphaKeyPressed('W')||keyCodePressed(38))this.speed+=accel;
        if(alphaKeyPressed('S')||keyCodePressed(40))this.speed-=accel;
        if(alphaKeyPressed('A')||keyCodePressed(37))this.angle+=rspeed;
        if(alphaKeyPressed('D')||keyCodePressed(39))this.angle-=rspeed;
        
        if(this.speed<0.0)this.speed=0;
        else if(this.speed>2.0)this.speed=2.0;
//  Handle tank movement
        var msin=Math.sin(this.angle);
        var mcos=Math.cos(this.angle);
        
        var groundSpeed=this.speed;
        
        var curCell=boloworld.getCellAtWorld(this.matrix[12],this.matrix[13]);
        var boatSpeed=0.75;
        groundSpeed *= boloworld.tileData[curCell[0].name].speed;
        if(!this.boat)
        {
            if(curCell[0].name=="River"||curCell[0].name=="Ocean")
            {
                for(var t=1;t<curCell.length;t++){
                    if(curCell[t].name=="boat"){
                        this.boat=curCell[t];
                    }
                }
            }
        }
        if(this.boat){
            if(curCell[0].name=="River"||curCell[0].name=="Ocean"){
                groundSpeed = this.speed * boatSpeed;
                
                boloworld.moveTileObject(this.boat,this.matrix[12],this.matrix[13],0.0);
                
                mat4.set(this.matrix,this.boat.matrix);
            }else{
                delete this.boat;
            }
        }
        moveObject(this,(-msin*groundSpeed),(mcos*groundSpeed),0.0,tankRad);
        
//Tank Firing
        if(alphaKeyPressed(' ')){
            if(!this.fireCooldown){
                this.fireCooldown=15;
                fireProjectile(this);
            }else{
                this.fireCooldown--;
            }
        }else if(this.fireCooldown){
            this.fireCooldown--;
        }

       

        var pmat=this.matrix;
        mat4.getRowV3(pmat, 3, this.camTarget);
        mat4.identity(pmat);
        mat4.translate(pmat,this.camTarget);
        mat4.rotateZ(pmat, this.angle)
        
        vec3.scale(this.camTarget,-1.0);   //Flip the coordinate so its in camera space..
        display.camera.setCenter(this.camTarget);
    }
    
    function sfrnd(rng){
        return ((Math.random()*rng)-(rng*0.5));
    }
    display.createFrameRenderer = function(gl,timing){
        return {
            gl:gl,
            timing:timing,
            update:function (gobj){	//render
                //console.log("rendering.");
                var comps=gobj.components;
                display.setWorld(gobj.matrix);
                for(var i=0;i<comps.length;i++){
                    var c=comps[i];
                    display.renderComponent(gobj,c,c.shader);
                }
            }
        }
    }

    
    display.renderFrame=function(gl,timing){

        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
	

        boloworld.update(gl,display,timing);
        
        
        display.renderActiveShaders();                
    }
	
    glUtil.startRenderLoop(gl, canvas, function(gl, timing) {
        fpsCounter.innerHTML = timing.framesPerSecond;		
        //gl.clearColor(1.0, 0.0, 0.1, 1.0);
        display.renderLoop(gl, timing);
    });
	
    function fullscreenchange() {
        if(document.webkitIsFullScreen || document.mozFullScreen) {
            canvas.width = screen.width;
            canvas.height = screen.height;
        } else {
            canvas.width = canvasOriginalWidth;
            canvas.height = canvasOriginalHeight;
        }
        display.resize(gl, canvas);
    }

    frame.addEventListener("webkitfullscreenchange", fullscreenchange, false);
    frame.addEventListener("mozfullscreenchange", fullscreenchange, false);
	
	
});
